package server

import (
	"net/http"
	"adai.design/homemaster/log"
	"encoding/json"
	"adai.design/homemaster/container"
	"adai.design/homemaster/container/accessory"
	"adai.design/homemaster/container/characteristic"
	"adai.design/homemaster/container/service"
	"time"
)


func webSocketService(s *Server) {
	http.HandleFunc("/homemaster", func(writer http.ResponseWriter, request *http.Request) {
		serveWs(s, writer, request)
	})
	log.Fatal(http.ListenAndServe(":80", nil))
}

func notifyListener(hub *Server, a *accessory.Accessory, s *service.Service, c *characteristic.Characteristic) {
	chars := []*Characteristic{{
		AccessoryID: a.UUID,
		ServiceId: s.ID,
		CharacteristicId: c.Id,
		Value: c.Value,
	}}

	data, _ := json.Marshal(chars)

	msg := &Message{
		Path: MsgPathCharacteristics,
		Method: MsgMethodPut,
		Data: data,
	}

	msgBuf, _ := json.Marshal(msg)
	log.Info("%s", string(msgBuf))
	hub.broadcast(msgBuf)
}

func Start() {
	hub := newServer()
	go webSocketService(hub)
	go hub.run()

	load := func() {
		container := container.GetContainer()
		for _, a := range container.Accessories {
			func(a *accessory.Accessory) {
				for _, s := range a.Services {
					func(a *accessory.Accessory, s *service.Service) {
						for _, c := range s.Characteristics {
							onChange := func(c *characteristic.Characteristic, new, old interface{}) {
								//log.Info("update aid(%s %d %d)", a.UUID, s.ID, c.Id)
								notifyListener(hub, a, s, c)
							}
							c.OnValueUpdate(onChange)
						}
					}(a, s)
				}
			}(a)
		}
	}

	master := container.GetContainer()
	// 容器设备列表发生变化造成的版本变化
	change := func(new, old int) {
		load()
		info := map[string]interface{}{
			"version":  container.GetContainer().Version,
			"firmware": "0.0.1",
			"date":     time.Now().Add(time.Hour * 8).Format("2006/01/02 15:04:05"),
		}

		data, _ := json.Marshal(info)
		put := &Message{
			Path:   MsgPathContainer,
			Method: MsgMethodPut,
			Data:   data,
			State:  "ok",
		}
		data, _ = json.Marshal(put)
		log.Debug("put (%s)", string(data))
	}


	master.OnVersionChange(change)
	go load()
}




